package projectisd.client;
/** 
 * In deze klas wordt de interface aangeroepen om een Les te kunnen toevoegen
 * in de webbrowse
 * @author Team 2
 * @version 7.0
 */
import java.util.List;
import java.util.Date;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.datepicker.client.DatePicker;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;

public class LesGUI {
	/* Constants. */
	private static final String LISTING_ROOT_PANEL = "guiListing";
	private static final String FORM_ROOT_PANEL = "guiForm";
	private static final String STATUS_ROOT_PANEL = "guiStatus";
	private static final String TOOL_BAR_ROOT_PANEL = "guiToolBar";
	private static final int EDIT_LINK = 9;
	private static final int REMOVE_LINK = 10;

	/* GUI Widgets */
	protected Button addButton;
	protected Button updateButton;
	protected Button addNewButton;
	protected ListBox docNrField;
	protected ListBox vakNrField;
	protected TextBox naamField;
	protected TextBox landField;
	protected TextBox lokaalField;
	protected TextBox beginTijdField;
	protected TextBox eindTijdField;
	protected Label titel;
	protected Label status;
	protected Grid listGrid;
	protected Grid formGrid;
	protected Image hulogo;

	private Label datePickerLabel;
	private DatePicker myDatePicker;
	private String dateString;

	/* Data model */
	private List<Leraar> leraren;
	private List<Vak> vakken;

	private List<Les> lessen;
	private Les currentLes;
	protected LesDelegate lesService;

	/** 
	 * In deze methode worden alle Widgets gemaakt die later weer kunnen worden opgehaald
	 */
	
	public void init() {
		addButton = new Button("Add les");
		addNewButton = new Button("Add new les");
		updateButton = new Button("Update les");
		docNrField = new ListBox();
		vakNrField = new ListBox();
		lokaalField = new TextBox();
		beginTijdField = new TextBox();
		eindTijdField = new TextBox();
		status = new Label();
		listGrid = new Grid(2,12);

		hulogo = new Image("http://jansen-schoonhoven.com/Downloads/hulogo.jpg");

		//Geboortedatum widget
		datePickerLabel = new Label();
		myDatePicker = new DatePicker();
		myDatePicker.addValueChangeHandler(new ValueChangeHandler() {
			public void onValueChange(ValueChangeEvent event) {
				Date date = (Date) event.getValue();
				dateString = DateTimeFormat.getMediumDateFormat().format(date);
				datePickerLabel.setText(dateString);
			}
		});

		titel = new Label("Lessen beheren");

		buildForm();
		placeWidgets();
	}
	
	/** 
	 * In deze methode wordt het formulier aangeroepen wat de gebruiker
	 * kan invullen	
	 */

	private void buildForm() {
		formGrid = new Grid(9,3);
		formGrid.setVisible(false);

		formGrid.setWidget(0, 0, titel);
		formGrid.setWidget(0, 2, hulogo);

		formGrid.setWidget(1, 0, new Label("Datum"));
		formGrid.setWidget(1, 1, myDatePicker); 

		formGrid.setWidget(2, 0, new Label("Begintijd"));
		formGrid.setWidget(2, 1, beginTijdField); 

		formGrid.setWidget(3, 0, new Label("Eindtijd"));
		formGrid.setWidget(3, 1, eindTijdField);     

		formGrid.setWidget(4, 0, new Label("Docent"));
		formGrid.setWidget(4, 1, docNrField);

		formGrid.setWidget(5, 0, new Label("Lokaal"));
		formGrid.setWidget(5, 1, lokaalField);

		formGrid.setWidget(6, 0, new Label("Cursus Code"));
		formGrid.setWidget(6, 1, vakNrField);

		formGrid.setWidget(7, 0, updateButton);
		formGrid.setWidget(7, 1, addButton);

	}
	
	/** 
	 * Hier in worden de widgets zoals listgrid formgrid en status geplaats in
	 * de rootpanel 
	 */

	private void placeWidgets() {
		RootPanel.get(LISTING_ROOT_PANEL).add(listGrid);
		RootPanel.get(FORM_ROOT_PANEL).add(formGrid);
		RootPanel.get(STATUS_ROOT_PANEL).add(status);
		RootPanel.get(TOOL_BAR_ROOT_PANEL).add(addNewButton);
	}
	
	/** 
	 * In deze methode wordt uitgevoerd om bepaalde widgets te kunnen hiden als deze wordt aangeroepen
	 */

	public void hideGui() {
		formGrid.setVisible(false);
		listGrid.setVisible(false);
		status.setVisible(false);
		addNewButton.setVisible(false);
	}
	
	/** 
	 * In deze methode wordt het formulier aangeroepen wat de gebruiker
	 * kan invullen	
	 */


	private void loadForm(Les les) {
		this.formGrid.setVisible(true);
		currentLes = les;

		this.docNrField.clear();
		int index = 0;
		int selected = 0;
		for (Leraar leraar : leraren) {
			this.docNrField.addItem(leraar.getAfkorting());
			if (les.getDocNr().longValue() == 
				leraar.getDocNr().longValue()) {
				selected = index;
			}
			index++;
		}        
		this.docNrField.setSelectedIndex(selected);

		this.vakNrField.clear();
		index = 0;
		selected = 0;
		for (Vak vak : vakken) {
			this.vakNrField.addItem(vak.getCode());
			if (les.getVakNr().longValue() == 
				vak.getVakNr().longValue()) {
				selected = index;
			}
			index++;
		}        
		this.vakNrField.setSelectedIndex(selected);
		this.datePickerLabel.setText(les.getDatum());
		this.beginTijdField.setText(les.getBegintijd());
		this.eindTijdField.setText(les.getEindtijd());
		this.lokaalField.setText(les.getLokaal());
	}
	
	/** 
	 * In deze methode wordt een Leerling opgeslagen in de database
	 * 
	 */


	private void copyFieldDateToLes() {

		int selected = this.docNrField.getSelectedIndex();

		Long docNr = 0L;
		if (leraren.size() > selected) {
			docNr = leraren.get(selected).getDocNr();
		}
		currentLes.setDocNr(docNr);

		selected = this.vakNrField.getSelectedIndex();

		Long vakNr = 0L;
		if (vakken.size() > selected) {
			vakNr = vakken.get(selected).getVakNr();
		}
		currentLes.setVakNr(vakNr);
		currentLes.setDatum(datePickerLabel.getText());
		currentLes.setBegintijd(beginTijdField.getText());
		currentLes.setEindtijd(eindTijdField.getText());
		currentLes.setLokaal(lokaalField.getText());
	}
	
	/** 
	 * In deze methode wordt verteld wanneer bepaalde knoppen 
	 * zichtbaar mogen zijn zodra er een bepaalde knop wordt geselecteerd
	 * 
	 */

	public void gui_eventListGridClicked(Cell cellClicked) {
		int row = cellClicked.getRowIndex();
		int col = cellClicked.getCellIndex();

		Les les = this.lessen.get(row);
		this.status.setText("Lokaal was " + les.getLokaal() + " clicked ");

		if (col==EDIT_LINK) {
			this.addNewButton.setVisible(false);
			this.updateButton.setVisible(true);
			this.addButton.setVisible(false);
			loadForm(les);
		} else if (col==REMOVE_LINK) {
			if (Window.confirm("Verwijderen les?")) {
				this.lesService.removeLes(les);
			}
		}
	}
	

	/** 
	 * In deze methode staat wat er moet gebeuren voordat op Updatebutton wordt
	 * geclickt voordat de ingevulde gegevens worden opgeslagen.
	 */


	public void gui_eventAddButtonClicked() {
		if	(datePickerLabel.getText().length() == 0 &&
				beginTijdField.getText().length() == 0 &&
				eindTijdField.getText().length() == 0 &&
				lokaalField.getText().length() == 0)
		{	Window.alert("Alle velden moeten gevuld zijn");
		} else if (datePickerLabel.getText().length() == 0)
		{	Window.alert("Datum moet geselecteerd worden");
		} else if (beginTijdField.getText().length() == 0)
		{	Window.alert("Begintijd moet gevuld worden");
		}  else if (!beginTijdField.getText().matches("^([0-1][0-9]|[2][0-3]):([0-5][0-9])$"))
		{	Window.alert("Begintijd mag alleen met hh:mm worden weergegeven");
		} else if (eindTijdField.getText().length() == 0)
		{	Window.alert("Eindtijd moet gevuld worden");
		}  else if (!eindTijdField.getText().matches("^([0-1][0-9]|[2][0-3]):([0-5][0-9])$"))
		{	Window.alert("Eindtijd mag alleen met hh:mm worden weergegeven");
		} else if (lokaalField.getText().length() == 0)
		{	Window.alert("Lokaal moet gevuld worden");
		}  else if (!lokaalField.getText().matches("^([A-Z][0-9][0-9]).([0-9][0-9])$") && lokaalField.getText().length() != 6)
		{	Window.alert("Lokaal mag alleen met een letter beginnen, gevolgd door twee cijfers en dan een punt met nog 2 cijfers");

		}	else { 
			addNewButton.setVisible(true);
			formGrid.setVisible(false);
			copyFieldDateToLes();
			this.lesService.addLes(currentLes);
		}
	}
	
	/** 
	 * In deze methode wordt verteld wanneer bepaalde knoppen 
	 * zichtbaar mogen zijn zodra er een bepaalde knop wordt geselecteerd
	 * 
	 */

	public void gui_eventUpdateButtonClicked() {
		if	(datePickerLabel.getText().length() == 0 &&
				beginTijdField.getText().length() == 0 &&
				eindTijdField.getText().length() == 0 &&
				lokaalField.getText().length() == 0)
		{	Window.alert("Alle velden moeten gevuld zijn");
		} else if (datePickerLabel.getText().length() == 0)
		{	Window.alert("Datum moet geselecteerd worden");
		} else if (beginTijdField.getText().length() == 0)
		{	Window.alert("Begintijd moet gevuld worden");
		}  else if (!beginTijdField.getText().matches("^([0-1][0-9]|[2][0-3]):([0-5][0-9])$"))
		{	Window.alert("Begintijd mag alleen met hh:mm worden weergegeven");
		} else if (eindTijdField.getText().length() == 0)
		{	Window.alert("Eindtijd moet gevuld worden");
		}  else if (!eindTijdField.getText().matches("^([0-1][0-9]|[2][0-3]):([0-5][0-9])$"))
		{	Window.alert("Eindtijd mag alleen met hh:mm worden weergegeven");
		} else if (lokaalField.getText().length() == 0)
		{	Window.alert("Lokaal moet gevuld worden");
		}  else if (!lokaalField.getText().matches("^([A-Z][0-9][0-9]).([0-9][0-9])$") && lokaalField.getText().length() != 6)
		{	Window.alert("Lokaal mag alleen met een letter beginnen, gevolgd door twee cijfers en dan een punt met nog 2 cijfers");
		}	else{
			addNewButton.setVisible(true);
			formGrid.setVisible(false);
			copyFieldDateToLes();
			this.lesService.updateLes(currentLes);
		}
	}
	

	/** 
	 * In deze methode staat wat er moet gebeuren voordat op Addbutton wordt
	 * geclickt voordat de ingevulde gegevens worden opgeslagen.
	 */

	public void gui_eventAddNewButtonClicked() {
		this.addNewButton.setVisible(false);
		this.updateButton.setVisible(false);
		this.addButton.setVisible(true);
		Les les = new Les();
		les.setDocNr(0L);
		les.setVakNr(0L);
		loadForm(les);
	}
	
	/** 
	 * In deze methode staat wat er moet gebeuren voordat op Updatebutton wordt
	 * geclickt voordat de ingevulde gegevens worden opgeslagen.
	 */

	public void service_lerarenListRetrievedFromService(List<Leraar> result) {
		this.leraren = result;	
	}

	public void service_vakkenListRetrievedFromService(List<Vak> result) {
		this.vakken = result;	
	}
	
	/** 
	 * In deze methode wordt de lijst getoont met een for
	 */

	public void service_eventListRetrievedFromService(List<Les> result) {
		status.setText("Retrieved les list");
		status.setVisible(true);

		//formGrid.setVisible(false);
		listGrid.setVisible(true);
		status.setVisible(true);
		addNewButton.setVisible(true);

		this.lessen = result;
		this.listGrid.clear();
		this.listGrid.resizeRows(this.lessen.size());
		int row = 0;
		this.addNewButton.setVisible(true);

		for (Les les : result) {
			if (vakken != null)
				if (leraren != null)
					for (Leraar leraar : leraren) {
						if (les.getDocNr().longValue() == 
							leraar.getDocNr().longValue()) {

							this.listGrid.setWidget(row, 0, new Label (les.getDatum()));
							this.listGrid.setWidget(row, 1, new Label (les.getBegintijd()));
							this.listGrid.setWidget(row, 2, new Label (les.getEindtijd()));
							this.listGrid.setWidget(row, 3, new Label (leraar.getAfkorting()));
							this.listGrid.setWidget(row, 4, new Label (leraar.getLeraarvoornaam()));
							this.listGrid.setWidget(row, 5, new Label (leraar.getLeraarachternaam()));
							this.listGrid.setWidget(row, 6, new Label (les.getLokaal()));
							for (Vak vak : vakken) {
								if (les.getVakNr().longValue() == 
									vak.getVakNr().longValue()) {
									this.listGrid.setWidget(row, 7, new Label (vak.getCode()));
									this.listGrid.setWidget(row, 8, new Label (vak.getName()));
									this.listGrid.setWidget(row, EDIT_LINK, new Hyperlink("Edit", null));
									this.listGrid.setWidget(row, REMOVE_LINK, new Hyperlink("Remove", null));
									row ++;
								}
							}
						}
					}
		}
	}
	
	/** 
	 * In deze methode wordt verteld of de gegevens goed zijn toegevoegd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventAddLesSuccessful() {
		status.setText("Les was successfully added");
		this.lesService.listLessen();
	}
	
	/** 
	 * In deze methode wordt verteld of de date goed is geupdated
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventUpdateSuccessful() {
		status.setText("Les was successfully updated");
		this.lesService.listLessen();
	}
	
	/** 
	 * In deze methode wordt verteld of de date goed is verwijderd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */
	public void service_eventRemoveLesSuccessful() {
		status.setText("Les was removed");
		this.lesService.listLessen();
	}
	
	/** 
	 * In deze methode wordt verteld of de date niet goed is geupdated
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventUpdateLesFailed(Throwable caught) {
		status.setText("Update les failed");
	}
	
	/** 
	 * In deze methode wordt verteld of de date niet goed is toegevoegd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */


	public void service_eventAddLesFailed(Throwable caught) {
		status.setText("Unable to update les");
	}
	
	/** 
	 * In deze methode wordt verteld of de date niet goed is verwijderd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventRemoveLesFailed(Throwable caught) {
		status.setText("Remove les failed");
	}
	
	/** 
	 * In deze methode wordt verteld of de date niet goed wordt getoont
	 * in de lijst
	 */

	public void service_eventListLessenFailed(Throwable caught) {
		status.setText("Unable to get les list");

	}

}
